package site.assad.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.*;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.stereotype.Repository;
import site.assad.domain.User;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;


/**
 * Author: Al-assad 余林颖
 * E-mail: yulinying_1994@outlook.com
 * Date: 2017/12/8 18:11
 * Description: 操作 User 领域对象的 DAO 对象
 */
//将 UserDao 标注为一个 DAO Bean
@Repository
public class UserDao {

    //自动注入 JdbcTemplate bean 对象
    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 演示查询过程，即sql中的 select 操作
     * */


    //演示查询操作(使用 RowCallbackHandler 处理结果集，单结果返回)
    public  User findUserByUserName(final String userName){

        //sql 模板
        final String sqlStr = "SELECT user_id,user_name,user_password,create_date " +
                "FROM users where user_name = ?";

        //创建接受结果的 domain 对象
        final User user = new User();

        //通过 jbdcTemplate 执行 sql 查询语句，参数1：sql 模板语句，参数2：sql 模板语句中占位符的实参，参数3：对于查询结果的回调逻辑
        jdbcTemplate.query(sqlStr, new Object[]{userName}, new RowCallbackHandler() {
            @Override
            public void processRow(ResultSet rs) throws SQLException {
                user.setId(rs.getInt("user_id"));
                user.setName(rs.getString("user_name"));
                user.setPassword(rs.getString("user_password"));
                user.setCreateDate(rs.getDate("create_date"));
            }
        });

        return user;
    }


    //演示查询操作(使用 RowCallbackHandler 处理结果集，多结果返回)
    public List<User> findUserByIcon(final String icon){
        final String sql = "SELECT user_id,user_name,create_date,user_icon " +
                "FROM users " +
                "WHERE user_icon = ?";

        final List<User> usersList = new ArrayList<>();  //记录结果集

        jdbcTemplate.query(sql, new Object[]{icon}, new RowCallbackHandler() {
            @Override
            public void processRow(ResultSet rs) throws SQLException {
                User user = new User();
                user.setId(rs.getInt("user_id"));
                user.setName(rs.getString("user_name"));
                user.setCreateDate(rs.getDate("create_date"));
                user.setIcon(rs.getString("user_icon"));
                usersList.add(user);
            }
        });

        return usersList;
    }



    //演示查询操作（使用 RowMapper<T> 处理结果集,多结果）
    public List<User> findUserByIconV2(final String icon){
        final String sql = "SELECT user_id,user_name,create_date,user_icon " +
                "FROM users " +
                "WHERE user_icon = ?";

        return jdbcTemplate.query(sql, new Object[]{icon}, new RowMapper<User>() {
            @Override
            public User mapRow(ResultSet rs, int rowNum) throws SQLException {
                User user = new User();
                user.setId(rs.getInt("user_id"));
                user.setName(rs.getString("user_name"));
                user.setCreateDate(rs.getDate("create_date"));
                user.setIcon(rs.getString("user_icon"));
                return user;
            }
        });
    }



    //演示单值查询
    public int getUserCount(){
        final String sql = "SELECT COUNT(*) FROM users";
        return jdbcTemplate.queryForObject(sql,Integer.class);
    }
    public User findUserByNameV2(final String username){
        final String sqlStr = "SELECT user_id,user_name,user_password,create_date " +
                "FROM users where user_name = ?";
        return jdbcTemplate.queryForObject(sqlStr,new Object[]{username},User.class);
    }



    /**
     * 演示更改过程，包括sql中的 update，delete，insert 操作
     * */
    //演示 insert 过程
    public void addUser (final User user){
        //创建 sql 模板
        String sqlStr = "INSERT INTO users(user_name,user_password,create_date,user_icon) " +
                " VALUES(?,PASSWORD(?),?,?)";
        //通过 jdbcTempalte 模板更新数据
        jdbcTemplate.update(sqlStr,new Object[]{user.getName(),user.getPassword(),user.getCreateDate(),user.getIcon()});

        /*实际上在使用 JdbcTemplate#update(String sql,Object[] params) 时候，JdbcTemplate 会根据 params 参数自动创建一个 PerparedStatementSetter 回调实例；
         实际上和 JdbcTemplate#update(String sql,PreparedStatementSetter pss) JdbcTemplate#update(String sql,PreparedStatmentCreator psc) 效果是一样的，
        一般使用时会直接使用以上示例的 update 方法，因为另外2种方法实际上没有增加额外的功能，而且会照成一定的代码冗余；*/
    }
    //演示 update 操作
    public void updatePassword(final String username,final String newPassword){
        final String sql = "UPDATE users " +
                "SET user_password = PASSWORD(?)" +
                "WHERE user_name = ?";
        jdbcTemplate.update(sql,new Object[]{username,newPassword});
    }
    //演示 remove 操作
    public void deleteUser(final User user){
       final  String sql = "DELETE FROM users " +
                "WHERE user_name = ?";
        jdbcTemplate.update(sql,new Object[]{user.getName()});
    }

    //演示批量操作
    public void addUsers(final List<User> userList){
        final String sql = "INSERT INTO users(user_name,user_password,create_date,user_icon) " +
                "VALUES (?,PASSWORD(?),?,?)";
        jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override //指定该批次的记录数
            public int getBatchSize() {
                return userList.size();
            }
            @Override //绑定插入的参数
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                User user = userList.get(i);
                ps.setString(1,user.getName());
                ps.setString(2,user.getPassword());
                ps.setDate(3, new java.sql.Date(user.getCreateDate().getTime()));
                ps.setString(4,user.getIcon());
            }
        });

    }




}
